package com.hup.utils.commons.start;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.util.StringUtils;

/**
 * 改进的AnnotationBeanNameGenerator;<pre>
 * 解决[proguard混淆代码后,(不同包之间)类名重复]的异常
 * .需要在main方法中配置: SpringApplicationBuilder.beanNameGenerator(new LongBeanNameGenerator())
 * .解决方案:beanName使用长类名[com.xx.xx.className](父类使用的是短类名)
 * .不影响如[@Component,@Bean(value = "xxa")]的自定义配置
 * .对于使用[@Bean+方法名]定义的组件,则需规范处理proguard问题:
 *      .尽量保证只有一个类存放@Bean
 *      .@Bean注解中配置好vaule属性,否则此类组件的组件名默认是方法名(某些场景下会导致重名异常)
 *
 * @author hugan
 * @date 2020/12/29
 */
public class LongBeanNameGenerator extends AnnotationBeanNameGenerator {

    @Override
    public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
        if (definition instanceof AnnotatedBeanDefinition) {
            //使用如[@Component(value = "xxa")]中的值,与父类一致
            String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
            if (StringUtils.hasText(beanName)) {
                //ShareLogger.info("FromAnnotation={}", beanName);
                return beanName;
            }
        }
        //如果没有自定义,则采用长类名
        //ShareLogger.info("getBeanClassName={}", definition.getBeanClassName());
        return definition.getBeanClassName();
    }

}
